home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’97
/
Invisible JEDI
/
source code
/
PixMapUtilities.cpp
next >
Wrap
Text File
|
1997-06-28
|
6KB
|
241 lines
/***********************************************************
PixMapUtilities.cpp
©1997 Eric Cole
***********************************************************/
void ShiftPixPat( PixPatHandle pixpat , long horz , long vert );
void FlipPixPat( PixPatHandle pixpat , long horz , long vert );
void InvertPixPat( PixPatHandle pixpat );
void VShiftPixMap( PixMapHandle pixmap , long dist );
void HShiftPixMap( PixMapHandle pixmap , long dist );
void RotateBitsLeft( void *data , UInt32 bits , void *buff , UInt32 move );
void RotateDataLeft( char *data , UInt32 size , char *buff , UInt32 move );
void RotateBitsRight( void *data , UInt32 bits , void *buff , UInt32 move );
void RotateDataRight( char *data , UInt32 size , char *buff , UInt32 move );
void InvertBits( char *bytes , int bits );
void InvertPixMap( PixMapPtr pix , char *base );
#ifndef StripAddress
#define StripAddress(x) x
#endif
void InvertBits( char *bytes , int bits ) {
register int i = ( bits / 8 );
while ( --i >= 0 ) bytes[i] = ~bytes[i];
// endian dependant
if ( bits & 7 ) {
i = (-1L) << ( bits & 7 );
bits /= 8;
bytes[bits] = ( bytes[bits] & ~i ) | ( ~bytes[bits] & i );
}
}
void InvertPixMap( PixMapPtr pix , char *base ) {
Rect *rect = &pix->bounds;
int bits = (unsigned long)( rect->right - rect->left ) * pix->pixelSize;
int tall = rect->bottom - rect->top;
int wide = pix->rowBytes & 0x3FFF;
while ( tall-- > 0 ) {
InvertBits( base , bits );
base += wide;
}
}
void InvertPixPat( PixPatHandle pixpat ) {
InvertPixMap( *(**pixpat).patMap , *(**pixpat).patData );
(**pixpat).patXValid = -1;
}
void ShiftPixPat( PixPatHandle pixpat , long horz , long vert ) {
Handle data = (**pixpat).patData;
int state = HGetState( data );
PixMapHandle pixmap = (**pixpat).patMap;
HLock( data );
(**pixmap).baseAddr = StripAddress( *data );
if ( horz ) HShiftPixMap( pixmap , horz );
if ( vert ) VShiftPixMap( pixmap , vert );
HSetState( data , state );
(**pixmap).baseAddr = nil;
(**pixpat).patXValid = -1;
}
void VShiftPixMap( PixMapHandle pixmap , long dist ) {
Ptr base , move , addr , dest = (**pixmap).baseAddr;
long diff , full , size = (**pixmap).rowBytes;
Rect rect = (**pixmap).bounds;
Ptr buff = NewPtr( size &= 0x3FFF );
if ( buff == nil || dest == nil ) return;
base = move = addr = dest;
full = ( rect.bottom - rect.top );
dist %= full;
full *= size;
full -= size;
if ( dist > 0 ) {
addr += full;
move += size;
diff = -1;
} else {
dest += full;
base += size;
diff = 1;
}
while ( dist ) {
BlockMoveData( addr , buff , size );
BlockMoveData( base , move , full );
BlockMoveData( buff , dest , size );
dist += diff;
}
DisposePtr( buff );
}
void RotateDataLeft( char *data , UInt32 size , char *buff , UInt32 move ) {
BlockMoveData( data , buff , move );
BlockMoveData( data + move , data , size - move );
BlockMoveData( buff , data + size - move , move );
}
void RotateDataRight( char *data , UInt32 size , char *buff , UInt32 move ) {
BlockMoveData( data + size - move , buff , move );
BlockMoveData( data , data + move , size - move );
BlockMoveData( buff , data , move );
}
// changes -- start on an arbitrary bit -- be endian aware
void RotateBitsLeft( void *data , UInt32 bits , void *buff , UInt32 move ) {
UInt8 *addr = (UInt8 *)data;
UInt8 mask , keep , temp;
if ( move == 0 || bits == 0 || data == nil || buff == nil ) return;
if ( move > 7 && bits > move ) {
if ( buff ) {
RotateDataLeft( (char *)addr , ( bits + 7 ) / 8 , (char *)buff , move / 8 );
} else return;
if ( bits & 7 ) {
temp = bits / 8;
keep = addr[temp-1];
mask = ( 0xFF << ( 8 - ( bits & 7 ) ) );
addr[temp-1] = ( keep & mask ) | ( addr[temp] >> ( bits & 7 ) );
addr[temp] = ( keep & ~mask ) | ( addr[temp] << ( 8 - ( bits & 7 ) ) );
}
}
keep = *addr;
move &= 7;
if ( move > bits ) move %= bits;
for ( temp = 8 - move ; bits >= 16 ; bits -= 8 , ++addr ) {
addr[0] = ( addr[0] << move ) | ( addr[1] >> temp );
}
if ( bits >= 8 ) {
temp = ( addr[1] & ( 0xFF << ( 16 - bits ) ) ) | ( keep >> ( bits - 8 ) );
addr[0] = ( addr[0] << move ) | ( temp >> ( 8 - move ) );
bits -= 8;
++addr;
}
if ( bits > 0 ) {
mask = ( 0xFF << ( 8 - bits ) );
temp = ( ( addr[0] & mask ) << move );
temp |= ( bits > move ) ? keep >> ( bits - move ) : keep << ( move - bits );
addr[0] = ( temp & mask ) | ( addr[0] & ~mask );
}
}
void RotateBitsRight( void *data , UInt32 bits , void *buff , UInt32 move ) {
return;
UInt8 *addr = (UInt8 *)data;
UInt8 mask , keep , temp;
if ( move == 0 || bits == 0 || data == nil || buff == nil ) return;
if ( move > 7 && bits > move ) {
if ( buff ) {
RotateDataRight( (char *)addr , ( bits + 7 ) / 8 , (char *)buff , move / 8 );
} else return;
if ( bits & 7 ) {
temp = bits / 8;
keep = addr[temp-1];
mask = ( 0xFF << ( 8 - ( bits & 7 ) ) );
addr[temp-1] = ( keep & mask ) | ( addr[temp] >> ( bits & 7 ) );
addr[temp] = ( keep & ~mask ) | ( addr[temp] << ( 8 - ( bits & 7 ) ) );
}
}
keep = *addr;
move &= 7;
if ( move > bits ) move %= bits;
for ( temp = 8 - move ; bits >= 16 ; bits -= 8 , ++addr ) {
addr[0] = ( addr[0] << move ) | ( addr[1] >> temp );
}
if ( bits >= 8 ) {
temp = ( addr[1] & ( 0xFF << ( 16 - bits ) ) ) | ( keep >> ( bits - 8 ) );
addr[0] = ( addr[0] << move ) | ( temp >> ( 8 - move ) );
bits -= 8;
++addr;
}
if ( bits > 0 ) {
mask = ( 0xFF << ( 8 - bits ) );
temp = ( ( addr[0] & mask ) << move );
temp |= ( bits > move ) ? keep >> ( bits - move ) : keep << ( move - bits );
addr[0] = ( temp & mask ) | ( addr[0] & ~mask );
}
}
void HShiftPixMap( PixMapHandle pixmap , long dist ) {
long deep = (**pixmap).pixelSize;
Ptr dest = (**pixmap).baseAddr;
long size = (**pixmap).rowBytes;
Rect rect = (**pixmap).bounds;
long wide = rect.right - rect.left;
Ptr buff = NewPtr( size &= 0x3FFF );
if ( buff == nil || dest == nil ) return;
dist %= wide;
while ( rect.top < rect.bottom ) {
RotateBitsLeft( dest , deep * wide , buff , ( ( ( dist < 0 ? 0 : wide ) - dist ) * deep ) );
dest += size;
rect.top += 1;
}
DisposePtr( buff );
}